﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Huirui.Cavan.Core.Extension;
using Huirui.Cavan.Domain.MainBoundedContext.SearchModule;
using Huirui.Cavan.Domain.MainBoundedContext.SystemModule;
using Huirui.Cavan.Domain.Seedwork;
using Spring.Context.Support;

namespace Huirui.Cavan.Application.MainBoundedContext.SystemModule
{
    public class DepartmentAppService : BaseAppService<Department, string, DepartmentSearch, IDepartmentRepository>, IDepartmentAppService
    {
        public override BoolGenericResult<Department> AddOrUpdate(Department entity)
        {
            Init();
            BoolGenericResult<Department> result = new BoolGenericResult<Department>();

            Employee employee = this.EmployeeAppService.GetBySearch(SearchFactory.CreateEmployeeSearch(SecurityAppService.UserAccount.Id)).FirstOrDefault();
            Administrator admin = new Administrator(employee);

            Department oldDepartment = null;
            if (entity.Id.IsNotEmpty())
            {
                oldDepartment = this.Repository.Get(entity.Id);
            }
            if (oldDepartment.IsNull())
            {
                IIDGenerateAppService idGenerateAppService = this.SpringContext.GetObject(SystemModuleConst.IDGENERATEAPPSERVICE, new object[] { employee.Corporation }) as IIDGenerateAppService;
                if (entity.Id.IsEmpty())
                {
                    entity.Id = idGenerateAppService.GenerateID(SystemIdentifier.BaseCodeRuleType.Department);
                }
                else
                {
                    idGenerateAppService.GenerateID(SystemIdentifier.BaseCodeRuleType.Department);
                }
                result = admin.AddDepartment(entity.Id, entity.Name, entity.Remark, entity.SuperiorDepartment);
                if (result.IsSuccess)
                    return base.Add(result.Object);
            }
            else
            {
                result = admin.UpdateDepartment(oldDepartment, entity.Name, entity.Remark, entity.SuperiorDepartment);
                if (result.IsSuccess)
                    return base.Update(result.Object);
            }
            return result;
        }

        public override BoolGenericResult<Department> Delete(Department entity)
        {
            IList<Department> lowerDepartments = this.GetBySearch(new DepartmentSearch() { ParentCode = entity.Id }).ToList();
            entity.IsDeleted = true;
            base.Update(entity);
            return DeleteChildDepartment(entity, lowerDepartments);
        }

        private BoolGenericResult<Department> DeleteChildDepartment(Department parent, IList<Department> lowerDepartments)
        {      
            while (lowerDepartments != null && lowerDepartments.Count > 0)
            {
                parent = lowerDepartments.FirstOrDefault();
                lowerDepartments = this.GetBySearch(new DepartmentSearch() { ParentCode = parent.Id }).ToList();
                parent.IsDeleted = true;
                base.Update(parent);
                return DeleteChildDepartment(parent, lowerDepartments);
            }
            parent.IsDeleted = true;
            return base.Update(parent);
        }
    }
}
